<?php
/**
 * Created by PhpStorm.
 * User: wangk
 * Date: 2016/11/29
 * Time: 14:34
 */
namespace common\helpers;

use Firebase\JWT\JWT;
use linslin\yii2\curl\Curl;
use yii\db\Exception;

class JWTHelper
{
    public static function urlsafeB64Decode($input)
    {
        $remainder = strlen($input) % 4;
        if ($remainder) {
            $padlen = 4 - $remainder;
            $input .= str_repeat('=', $padlen);
        }
        return base64_decode(strtr($input, '-_', '+/'));
    }

    /**
     * 将数组按key的ASCII顺序排列，并连接
     * @param array $dict
     * @return string
     */
    public static function sortAndJoinParams($dict)
    {
        if (empty($dict) || !is_array($dict)) {
            throw new \InvalidArgumentException('params必须是数组');
        }

        ksort($dict);
        reset($dict);
        $buff = "";
        foreach ($dict as $k => $v) {
            if ($v === null || $v === '') {
                continue;
            }
            $buff .= $k . "=" . $v . "&";
        }
        $buff = trim($buff, "&");
        return $buff;
    }


    /**
     * 获取命名, 支付querystring parameter和header获取
     * @param string $queryParamName
     * @return array|mixed
     */
    public static function getSignature($queryParamName = 'jwt')
    {
        $signature = \Yii::$app->request->get($queryParamName);
        if (!$signature) {
            $authHeader = \Yii::$app->request->getHeaders()->get('Authorization');
            if ($authHeader !== null && preg_match('/^Bearer\s+(.*?)$/', $authHeader, $matches)) {
                $signature = $matches[1];
            }
        }
        return $signature;
    }

    /**
     * 生成 JWT Token
     * @param $key
     * @param $secret
     * @param $expireTime
     * @param array $data
     * @return string
     */
    public static function generateToken($key, $secret, $expireTime, array $data)
    {
        $payload = [
            'iss' => $key,
            'exp' => $expireTime
        ];
        if (!empty($data)) {
            $payload['data'] = self::sortAndJoinParams($data);
        }
     //   return  JWT::encode($payload, $secret);
        return JWT::encode($payload, $secret);
    }


    /**
     * 发送通知到支付网关
     * @param $params
     * @param $sendUrl
     * @return mixed
     */
    public static function sendRequestToOderApi($params, $sendUrl,$payConfig,$method='post')
    {
        $signature = JWTHelper::generateToken(
            $payConfig['apiKey'],
            $payConfig['apiSecret'],
            time() + 3600,
            $params
        );

        $header = [
            sprintf('Authorization: Bearer %s', $signature),
        ];

        $postUrl = $payConfig['orderApiUrl']; // api 在网关中的地址

        $curl = new Curl();
        if($method == 'post'){
            $response = $curl
                ->setOption(CURLOPT_HTTPHEADER, $header)
                ->setOption(CURLOPT_POSTFIELDS, http_build_query($params))
                ->post($postUrl . $sendUrl);
        }else{
            $response = $curl
                ->setOption(CURLOPT_HTTPHEADER, $header)
                ->get($postUrl . $sendUrl);
        }

        if ($curl->responseCode != 200) {
            throw new InvalidCallException("调用服务失败");
            $obj = null;
        }else{
            $obj = json_decode($response, JSON_UNESCAPED_UNICODE);
        }
        return $obj;
    }

    /**
     * 获取app信息
     * @param $params
     * @param $sendUrl
     * @param $config
     * @param $auth_info
     * @param string $method
     * @return array|mixed|null
     * @throws Exception
     */
    public static function sendRequestToAuthApp($params, $sendUrl,$config,$auth_info,$method='post'){
        $curl = new Curl();
        $kong_api_url = $auth_info['url'];
        $auth_info['key'] = self::generateAppAuthKey($auth_info);

        unset($auth_info['secret_key']);
        unset($auth_info['url']);

        $auth_info = $curl->setOption(CURLOPT_POSTFIELDS, $auth_info)->post($kong_api_url);
        $data = json_decode($auth_info,JSON_UNESCAPED_UNICODE);

        if($data['success'] == 0){
            throw new Exception($data['message']);
        }
        $header = [
            sprintf('Authorization:Bearer %s', $data['data']),
        ];
        $postUrl = $config['AuthAppApiUrl']; // api 在网关中的地址
        $curl = new Curl();
        if($method == 'post'){
            $response = $curl
                ->setOption(CURLOPT_HTTPHEADER, $header)
                ->setOption(CURLOPT_POSTFIELDS, $params)
                ->setOption(CURLOPT_SSL_VERIFYPEER,false)
                ->setOption(CURLOPT_SSL_VERIFYHOST,false)
                ->setOption(CURLOPT_RETURNTRANSFER,1)
                ->post($postUrl . $sendUrl);
        }else{
            $sendUrl = $sendUrl.'?'.http_build_query($params);
            $response = $curl
                ->setOption(CURLOPT_HTTPHEADER, $header)
                ->setOption(CURLOPT_SSL_VERIFYPEER,false)
                ->setOption(CURLOPT_SSL_VERIFYHOST,false)
                ->setOption(CURLOPT_RETURNTRANSFER,1)
                ->get($postUrl .$sendUrl);
        }

        if ($curl->responseCode != 200) {
            throw new Exception("调用服务失败");
            $obj = null;
        }else{
            $obj = json_decode($response, JSON_UNESCAPED_UNICODE);
        }
        return $obj;
    }

    /**
     * 生成KongAPI的key
     * @param $params
     * @return string
     */
    private static function generateAppAuthKey($params){
        return md5($params['tenant_code'].$params['time'].$params['secret_key']);
    }


}